﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Horizontal Lines
    /// </summary>
    public class HorizontalLines : BaseImageFilter
    {
        int nR = 10;
        int nG = 10;
        int nB = 10;

        bool m_bReplaceColors = true;

        /// <summary>
        /// Initializes a new instance of the <see cref="HorizontalLines"/> class.
        /// </summary>
        public HorizontalLines()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="HorizontalLines"/> class.
        /// </summary>
        /// <param name="_nR">The _n R.</param>
        /// <param name="_nG">The _n G.</param>
        /// <param name="_nB">The _n B.</param>
        /// <param name="_bReplaceColors">if set to <c>true</c> [_b replace colors].</param>
        public HorizontalLines(int _nR, int _nG, int _nB, bool _bReplaceColors)
        {
            nR = _nR;
            nG = _nG;
            nB = _nB;
            m_bReplaceColors = _bReplaceColors;
        }

        /// <summary>
        /// used by clone to create a deep copy
        /// </summary>
        /// <param name="_horizontalLines"></param>
        internal HorizontalLines(HorizontalLines _horizontalLines)
        {
                this.nR = _horizontalLines.nR;
            this.nG = _horizontalLines.nG;
            this.nB = _horizontalLines.nG;
            this.m_bReplaceColors = _horizontalLines.m_bReplaceColors;
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;

            //TODO: don't use dictionary, speed up
            Dictionary<Point, Color> aColorPoint = new Dictionary<Point, Color>();

            int nHeight = _bitmap.Height;
            int nWidth = _bitmap.Width;

            int y = 0;
            int x = 0;

            Color colorToReplace = Color.Transparent;
            Color color1stRow = Color.Transparent;
            Color color2ndRow = Color.Transparent;

            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth - 1; x++)
                {
                    colorToReplace = Color.Transparent;
                    color1stRow = bitmap.GetPixel(x, y);
                    color2ndRow = bitmap.GetPixel(x + 1, y);

                    if (ColorFunctions.IsInColorTolerance(color1stRow, color2ndRow, nR, nG, nB))
                    {
                        if (m_bReplaceColors)
                        {
                            colorToReplace = Color.White;
                        }
                        else
                        {
                            colorToReplace = color1stRow;
                        }
                        if (!aColorPoint.ContainsKey(new Point(x, y))) aColorPoint.Add(new Point(x, y), colorToReplace);
                        if (!aColorPoint.ContainsKey(new Point(x + 1, y))) aColorPoint.Add(new Point(x + 1, y), colorToReplace);
                    }
                    else
                    {
                        if (!aColorPoint.ContainsKey(new Point(x, y))) aColorPoint.Add(new Point(x, y), Color.Black);
                        if (!aColorPoint.ContainsKey(new Point(x + 1, y))) aColorPoint.Add(new Point(x + 1, y), Color.Black);
                    }
                }
            }

            //TODO: HorizontalLines, integrate this foreach into upper for inner loop
            foreach (KeyValuePair<Point, Color> keyValuePair in aColorPoint)
            {
                bitmap.SetPixel(keyValuePair.Key.X, keyValuePair.Key.Y, keyValuePair.Value);
            }
            return _bitmap;
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new HorizontalLines(this);
        }
    }
}
